<?php

namespace App\Common\Lib\Err\Exception;

use App\Common as com;

class Render extends com\Lib\LibBase {
	protected $exception = null;

	public function __construct( \Throwable $exception ) {
		$this->exception = $exception;
		//
		parent::__construct();
	}

	/**
	 * 记录到数据库
	 * @param \Throwable $e 异常
	 * @return int 执行状态。[0]失败 [1]成功
	 */
	public function renderToDatabase() {
		// 检查是否记录异常
		if( $this->isRecord() != 1 ) return 1;
		//
		$data = [
			// 'name'    => get_class($exception),
			'file' => $this->exception->getFile(),
			'line' => $this->exception->getLine(),
			'message' => $this->exception->getMessage(),
			'trace' => $this->exception->getTrace(),
			'code' => $this->exception->getCode(),
			'source' => $this->getSourceCode(),
			'datas' => $this->getExtendData(),
			'tables' => [
				'GET FieldStruct' => $_GET,
				'POST FieldStruct' => $_POST,
				'Files' => $_FILES,
				'Cookies' => $_COOKIE,
				'Session' => isset( $_SESSION ) ? $_SESSION : [],
				'Server/ApiRequest FieldStruct' => $_SERVER,
				'Environment Variables' => $_ENV,
			],
			'server_info' => [
				'server_sid' => com\Cla\Com\Tool\Server::getNameSid(),
			]
		];

		com\Model\ExceptionLog::saveData( [
			'extract_exception_info' => $data,
		] );
		return 1;
	}

	/**
	 * 是否需要记录异常
	 * @return int 是否记录异常。[0]不记录 [1]记录
	 */
	protected function isRecord() {
		// 本地不记录
		// if( com\Lib\Debug::isLocality() ) return 0;
		//
		$status = $this->isRecordSubCheckErrCode();
		if( $status == 0 ) return 0;
		//
		$status = $this->isRecordSubCheckErrMessage();
		if( $status == 0 ) return 0;
		//
		return 1;
	}

	/**
	 * 是否需要记录异常->检查错误代码
	 * @return int 是否记录异常。[0]不记录 [1]记录
	 */
	protected function isRecordSubCheckErrCode() {
		$no_record_exception_code = [
			-16000300,
			-16000500,
			61023,
		];
		if( in_array( $this->exception->getCode(), $no_record_exception_code ) ){
			return 0;
		} else{
			return 1;
		}
	}

	/**
	 * 是否需要记录异常->检查错误信息
	 * @return int 是否记录异常。[0]不记录 [1]记录
	 */
	protected function isRecordSubCheckErrMessage() {
		$no_record_exception_message = [
			'Exception Throw Notic'
		];
		if( in_array( $this->exception->getMessage(), $no_record_exception_message ) ){
			return 0;
		} else{
			return 1;
		}
	}

	/**
	 * 获取出错文件内容
	 * 获取错误的前9行和后9行
	 * @return array 错误文件内容
	 */
	protected function getSourceCode() {
		// 读取前9行和后9行
		$line = $this->exception->getLine();
		$first = ( $line - 9 > 0 ) ? $line - 9 : 1;

		try{
			$contents = file( $this->exception->getFile() );
			$source = [
				'first' => $first,
				'source' => array_slice( $contents, $first - 1, 19 ),
			];
		} catch( \Exception $e ){
			$source = [];
		}
		return $source;
	}

	/**
	 * 获取异常扩展信息
	 * 用于非调试模式html返回类型显示
	 * @return array                 异常类定义的扩展数据
	 */
	protected function getExtendData() {
		$data = [];
		if( $this->exception instanceof \think\Exception ){
			$data = $this->exception->getData();
		}
		return $data;
	}

}
